package com.layer8.RPS;

import android.app.Activity;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.Random;

/**
 * Created by Devin Collins <agent14709@gmail.com>
 * Purpose: This class handles the actual battle functionality
 *  between two pets.
 */
public class Battle extends Activity {

    // Private variables used throughout the entire class
    TextView txtResults, txtLife, txtOLife;
    Pet pet, oPet;

    /**
     * FUNCTION
     * Name: onCreate
     * Accepts: bundle <savedInstanceState>
     * Returns: void
     * Purpose: This is the primary function called when the
     *  intent first loads.  Handles setting up the UI for
     *  user interaction.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.battle);

        // Create localized variables to be used by this function
        Button btnPhys = (Button) findViewById(R.id.btnPhys);
        Button btnMag = (Button) findViewById(R.id.btnMag);
        Button btnGrap = (Button) findViewById(R.id.btnGrap);
        Button btnNewGame = (Button) findViewById(R.id.btnNewGame);


        // Assign the class variables from above
        txtLife  = (TextView) findViewById(R.id.txtlife);
        txtOLife = (TextView) findViewById(R.id.txtolife);
        txtResults = (TextView) findViewById(R.id.txtResults);

        // Gets the users saved pet and loads it
        getSavedPet();

        // Creates a new game and initializes all variables
        newGame();

        // Assigns the primary "battle" buttons
        btnPhys.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                match("physical");
            }
        });
        btnMag.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                match("magical");
            }
        });
        btnGrap.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                match("grapple");
            }
        });

        // Sets up the hidden New Game button
        btnNewGame.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                newGame();
            }
        });
    }

    /**
     * FUNCTION
     * Name: newGame
     * Accepts: null
     * Returns: void
     * Purpose: This initalizes our main variables, finishes off the UI
     *  and gets a new opponent pet to fight
     */
    private void newGame() {
        // Change the layout back to the battle layout
        changeLayout("NewGame");
        // Reset our pets health back to maximum
        pet.setCurrHealth(pet.getStamina());
        // Get a new opponent to challenge
        oPet = getOpponent();
        // Create a new drawable used for our opponent pet image
        Drawable d = getResources().getDrawable(oPet.getImage());
        // Create the holder for our opponent pet image
        ImageView iOPet = (ImageView) findViewById(R.id.imgOPet);
        // Put the opponent pet image in it's place
        iOPet.setImageDrawable(d);
        // Reset the health counters
        txtLife.setText(String.valueOf(pet.getCurrHealth()));
        txtOLife.setText(String.valueOf(oPet.getCurrHealth()));
        // Clear the text of the results box
        txtResults.setText("");
    }

    /**
     * FUNCTION
     * Name: getRandomIn
     * Accepts: int <maxValue>
     * Returns: int
     * Purpose: This function returns a random integer
     *  between 0 and <maxValue>
     */
    private int getRandomInt(int maxValue) {
        // Create a new random number generator
        Random randomGen = new Random();
        // Get a new random number between 0 and <maxValue>
        return randomGen.nextInt(maxValue);
    }

    /**
     * FUNCTION
     * Name: getOpponent
     * Accepts: null
     * Returns: Pet
     * Purpose: Loads a new pet to challenge
     */
    private Pet getOpponent() {
        // Create a new instance of all pets
        PetLoader petLoader = new PetLoader(this);
        // Get an index for the opponent pet from the array
        int id = getRandomInt(petLoader.getLength());
        // Get the new pet
        return petLoader.getPet(id);
    }

    /**
     * FUNCTION
     * Name: getSavedPet()
     * Accepts: null
     * Returns: void
     * Purpose: Gets the saved pet from the preferences and initializes
     *  it into memory.
     */
    private void getSavedPet() {
        // Create a browser for our apps preferences
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        // Read the petID into memory, or choose a default 0
        int petID = prefs.getInt("petID", 0);
        // Create a new instance of all pets
        PetLoader petLoader = new PetLoader(this);
        // Load our pet based on the index from earlier
        pet = petLoader.getPet(petID);
        // Create a reference to our pets image holder
        ImageView iPet = (ImageView) findViewById(R.id.imgPet);
        // Create a drawable for our pet
        Drawable d = getResources().getDrawable(pet.getImage());
        // Assign the pet image to the proper holder
        iPet.setImageDrawable(d);
    }

    /**
     * FUNCTION
     * Name: match
     * Accepts: int <code>
     * Returns: void
     * Purpose: Handles the actual math and calculations when battling
     */
    private void match(String code) {
        // Create a random integer between 0 and 75 for our opponents battle choice
        int opponent = getRandomInt(75);
        // Determine who won
        int result = vs(code, opponent);
        // If we tied
        if (result == 0) {
            // Notify user we tied
            txtResults.setText("Tie");
            // Deal 10% of damage to both pets based on current health
            pet.dealDamage(pet.getCurrHealth() * .10);
            oPet.dealDamage(oPet.getCurrHealth() * .10);
        // If we lose
        } else if (result == -1) {
            // Notify the user we lost
            txtResults.setText("Lose :(");
            // Create a holder for our damage multiplier
            double damage = 1;
            // If the opponent chose a physical attack
            if (opponent <= 25) {
                // Assign the damage multiplier based on the opponents strength multiplier
                damage = oPet.getStrPhys();
                // Notify user of the result
                txtResults.setText(txtResults.getText() + "\nPhysical attack! x" + oPet.getStrPhys());
            // If the opponent chose a magical attack
            } else if (opponent > 25 && opponent <= 50) {
                // Assign the damage multiplier based on the opponents magic  multiplier
                damage = oPet.getStrMag();
                // Notify user of the result
                txtResults.setText(txtResults.getText() + "\nMagical attack! x" + oPet.getStrMag());
            // If the opponent chose a grapple attack
            } else if (opponent  > 50) {
                // Assign the damage multiplier based on the opponents grapple multiplier
                damage = oPet.getStrGrap();
                // Notify user of the result
                txtResults.setText(txtResults.getText() + "\nGrapple attack! x" + oPet.getStrGrap());
            }
            // Deal damage to our pet based on ((Opponent Base Strength / 10) * Multiplier)
            pet.dealDamage((oPet.getBase() / 10) * damage);
        // If we win
        } else if (result == 1) {
            // Notify the user we won
            txtResults.setText("Win!");
            // Set the damage multiplier
            double damage = 1;
            // If we performed a physical attack
            if (code.equals("physical")) {
                // Set the damage multiplier based on our physical multiplier
                damage = pet.getStrPhys();
                // Notify the user of the result
                txtResults.setText(txtResults.getText() + "\nPhysical attack! x" + pet.getStrPhys());
            // If we performed a magical attack
            } else if (code.equals("magical")) {
                // Set the damage multiplier based on our magical multiplier
                damage = pet.getStrMag();
                // Notify the user of the result
                txtResults.setText(txtResults.getText() + "\nMagical attack! x" + pet.getStrMag());
            // If we performed a grapple attack
            } else if (code.equals("grapple")) {
                // Set the damage multiplier based on our grapple multiplier
                damage = pet.getStrGrap();
                // Notify the user of the result
                txtResults.setText(txtResults.getText() + "\nGrapple attack! x" + pet.getStrGrap());
            }
            // Deal damage to the opponent based on ((Pet Base Strength / 10) * Multiplier)
            oPet.dealDamage((pet.getBase() / 10) * damage);
        }
        // If our health is less than 0 and the opponent health is higher than 0
        if (pet.getCurrHealth() <= 0 && oPet.getCurrHealth() > 0) {
            // We lose the match
            gameOver("Lose");
        // If opponent health is less than 0 and our health is higher than 0
        } else if (oPet.getCurrHealth() <= 0 && pet.getCurrHealth() > 0) {
            // We win the match
            gameOver("Win");
        // If our health is less than 0 and the opponent health is less than 0
        } else if (oPet.getCurrHealth() <= 0 && pet.getCurrHealth() <= 0) {
            // We tie
            gameOver("Tie");
        // Otherwise, the match continues
        } else {
            // Notify the user of both pets' health
            txtLife.setText(String.valueOf(pet.getCurrHealth()));
            txtOLife.setText(String.valueOf(oPet.getCurrHealth()));
        }
    }


    private void gameOver(String status) {
        changeLayout("GameOver");
        TextView txtResults = (TextView) findViewById(R.id.txtBattleResult);
        txtResults.setText(status);
    }

    private void changeLayout(String status) {
        LinearLayout llResults = (LinearLayout) findViewById(R.id.llResults);
        LinearLayout llBattle = (LinearLayout) findViewById(R.id.llBattle);
        if (status.equals("GameOver")) {
            llBattle.setVisibility(View.GONE);
            llResults.setVisibility(View.VISIBLE);
        } else if (status.equals("NewGame")) {
            llBattle.setVisibility(View.VISIBLE);
            llResults.setVisibility(View.GONE);
        }
    }

    private int vs(String code, int opponent) {
        int result = 0;
        if (code.equals("physical")) {
            if (opponent > 25 && opponent <= 50) {
                result = -1;
            } else if (opponent > 50) {
                result = 1;
            }
        } else if (code.equals("magical")) {
            if (opponent <= 25) {
                result = 1;
            } else if (opponent > 50) {
                result = -1;
            }
        } else if (code.equals("grapple")) {
            if (opponent <= 25) {
                result = -1;
            } else if (opponent > 25 && opponent <= 50) {
                result = 1;
            }
        }
        return result;
    }

}
